❯❯ 結合 vibe-setup 與 vibe-e2e:完成架構分層並自動補測(覆蓋 49 檔 / 175 條測試)
📍 流水線位置|入口 → flow → 型別 → mock → 測試 → UI → 【vibe】 → 上線(補測)

宴客當天,現場大多直接用手機操作。但原本的「桌次規劃頁」只支援拖曳排位,直到實際拿手機測試才發現:在小螢幕上,手指根本很難精準把賓客拖進指定座位。
於是,我加了一條觸控備援機制:點選賓客,再點擊座位,兩下完成入座。
這種互動,原始業務規格從沒定義過。它不是規格漏寫,而是介面真正落到真實場景後,自然演化出來的體驗優化。即便只是個小細節,一旦出錯,使用者體驗依然會打折扣。
但問題來了:隨著這類 UI 微調與新互動越來越多,如果每個細節都要工程師手動補寫 E2E 測試,時間根本不夠用。
為了解決這個痛點,開發流水線導入了 vibe-setup 與 vibe-e2e 這兩支自動化腳本,讓系統自動判斷「改動是否需要補測試」以及「該如何自動補齊」。
vibe-setup 變更分層當前端視覺與互動調整完畢、通過本地 gate 後,會在 terminal 跑 vibe-setup。這支腳本會靜態解析 git diff,將所有改動精準歸類為三個層級:
結構(Structure):
新增 DOM 區域、頁面元件、狀態條件渲染(loading、error、空狀態)。這類改動動到 DOM 節點的存在性,必須補測試。
互動(Interaction):
切換(toggle)、tab 頁籤、排序、拖曳備援這類行為邏輯。有邏輯狀態變化,必須補測試。
純視覺(Visual):
色票、間距、邊框、字體尺寸。不影響功能邏輯,直接略過測試。
分類機制是透過規則檔分析 git diff 裡的特定語法訊號,遵循「先判斷結構,再看互動,剩餘皆為純視覺」的優先順序:
結構訊號:
偵測到新增 <section> 語意標籤、v-if="loading" 條件渲染,或使用了 USkeleton、UAlert 等這類 NuxtUI 視覺元件。
互動訊號:
偵測到新增 @click 事件綁定、布林值 ref 宣告,或 .value = ! 這類開關切換寫法。
邊界情境:
如果 @click 只是位置轉移(按鈕 A 換到按鈕 B)而底層邏輯未變,系統會判定為純視覺調整,不列入互動變更。
每個解析出的訊號都會被標上對應的子模式(如 loading-state、toggle、tab),直接作為下一步 vibe-e2e 載入的 Playwright 測試模板的依據。

腳本執行完畢後,會輸出全新的「分層解析報告」:每個 hunk 屬於哪種變更層級、觸發了哪些測試模式,全數一目了然。
報告同時會執行 data-testid 檢查:將 git diff 中新增的 data-testid 與主規格測試(Main Spec)的白名單比對。存在於白名單中的屬「核心合約定位點」;其餘不在白名單內的,則判定為 Vibe 階段擴充的定位點,系統會依規範統一加上 vibe-* 前綴,藉此與主合約的命名空間(Namespace)做清晰隔離。開發者只要快速確認分類無誤,即可順暢切換到下一個階段。
vibe-e2e,自動生成測試vibe-e2e 會讀取上一步的分層報告,針對「結構」與「互動」類的變更,自動套用對應的 Playwright 測試模板。生成的測試檔統一放在 test/e2e/vibe/ 目錄,,命名邏輯如下:
interaction-reception-mobile-1.spec.ts (接待台手機體驗)
interaction-reception-batch-checkin-1.spec.ts (批量報到)
interaction-guests-batch-1.spec.ts (賓客批次操作)
檔案生成後,工具鏈會立即執行一次自動驗證。只要通過測試,這些案例就會正式納入專案的「迴歸測試防線」。未來任何變更若意外破壞了這些互動,gate 都會在第一時間攔截。
💡 抗干擾機制: 針對具備時序敏感度的測試(例如過渡動畫、Timer 輪詢等),系統會自動將其隔離至獨立目錄,避免產生不穩定的 Flaky Tests 干擾 CI/CD 主流程的判定。
目前 test/e2e/vibe/ 下累積了 49 個測試檔、175 條測試案例,規模甚至超過了主規格測試(Main Spec)的 150 條。其核心構成包含自動生成的 interaction-* 與 structure-* 系列,以及少量針對資料持久化與安全性的手動測試腳本。
主規格測試跟 vibe 測試在系統裡扮演不同角色:
| 測試類型 | 核心定位 | 變更處置原則 |
|---|---|---|
| 主規格測試 | 業務邏輯合約 | 嚴格凍結。 測試失敗代表業務邏輯壞掉,必須修程式碼,嚴禁修改測試檔。 |
| vibe 測試 | UI 行為快照紀錄 | 允許演進。 記錄最新 UI 行為;若失敗經評估為預期變更,可重新生成(Regenerate)覆蓋舊快照。 |

回到開頭那個觸控備援的例子。當時為了改善行動端拖曳座位不順手的痛點,加了「點選賓客 → 點選座位」的備援路徑,自動生成的測試檔 interaction-seating-tap-assign-1.spec.ts 內容如下(節錄):
// AUTO-GENERATED by /vibe-e2e — edit via regenerate(/vibe-e2e 同來源覆蓋)
// Pattern: tap-to-assign(互動:點選待放置 → 點座位 commit;issue #73 觸控備援)
await page.getByTestId('vibe-seating-guest-guest-001').tap()
await expect(page.getByTestId('vibe-seating-pending-bar')).toContainText('陳大明')
這支自動生成的腳本落實了兩件事:
vibe-* 前綴,避免侵入主規格測試的命名空間。之後如果互動邏輯變更需要更新這支測試,工程師完全不用手動修改腳本,只需再次執行vibe-e2e 以同來源重新生成,覆蓋舊檔即可。
這整支測試我一行都沒寫。我唯一做的事只有:確認分層報告無誤、驗收測試結果,僅此而已。
在規範、CI 門禁與自動化補測機制全都建立完畢後,下一篇,我們來聊聊這套機制在實際開發中,成功攔下的真實事故。
📎 本篇證據|
- test/e2e/vibe/(49 檔 175 條,
interaction-*系列檔名)- interaction-seating-tap-assign-1.spec.ts(
AUTO-GENERATED檔頭與vibe-*定位點)- commit
c28548e「test(e2e): vibe spec for tap-to-assign touch path」